// utils/mortgageCalculator.js

/**
 * 房贷计算器工具类
 */
class MortgageCalculator {
  /**
   * 等额本息计算
   * @param {number} loanAmount - 贷款金额
   * @param {number} loanTerm - 贷款期限（年）
   * @param {number} interestRate - 年利率
   * @returns {object} 计算结果
   */
  static equalPayment(loanAmount, loanTerm, interestRate) {
    const monthlyRate = interestRate / 12;
    const totalMonths = loanTerm * 12;
    
    if (monthlyRate === 0) {
      const monthlyPayment = loanAmount / totalMonths;
      return {
        monthlyPayment,
        totalInterest: 0,
        totalPayment: loanAmount,
        paymentSchedule: this.generateSchedule(loanAmount, totalMonths, monthlyPayment, 0)
      };
    }
    
    const monthlyPayment = loanAmount * (monthlyRate * Math.pow(1 + monthlyRate, totalMonths)) / 
                          (Math.pow(1 + monthlyRate, totalMonths) - 1);
    
    const totalPayment = monthlyPayment * totalMonths;
    const totalInterest = totalPayment - loanAmount;
    
    return {
      monthlyPayment,
      totalInterest,
      totalPayment,
      paymentSchedule: this.generateSchedule(loanAmount, totalMonths, monthlyPayment, monthlyRate)
    };
  }
  
  /**
   * 等额本金计算
   * @param {number} loanAmount - 贷款金额
   * @param {number} loanTerm - 贷款期限（年）
   * @param {number} interestRate - 年利率
   * @returns {object} 计算结果
   */
  static equalPrincipal(loanAmount, loanTerm, interestRate) {
    const monthlyRate = interestRate / 12;
    const totalMonths = loanTerm * 12;
    const monthlyPrincipal = loanAmount / totalMonths;
    
    let totalInterest = 0;
    let totalPayment = 0;
    const paymentSchedule = [];
    
    for (let i = 1; i <= totalMonths; i++) {
      const remainingBalance = loanAmount - (monthlyPrincipal * (i - 1));
      const monthlyInterest = remainingBalance * monthlyRate;
      const monthlyPayment = monthlyPrincipal + monthlyInterest;
      
      totalInterest += monthlyInterest;
      totalPayment += monthlyPayment;
      
      paymentSchedule.push({
        period: i,
        payment: monthlyPayment,
        principal: monthlyPrincipal,
        interest: monthlyInterest,
        remainingBalance: remainingBalance - monthlyPrincipal
      });
    }
    
    return {
      monthlyPayment: paymentSchedule[0].payment, // 首月还款额
      totalInterest,
      totalPayment,
      paymentSchedule
    };
  }
  
  /**
   * 生成还款计划表
   * @param {number} loanAmount - 贷款金额
   * @param {number} totalMonths - 总月数
   * @param {number} monthlyPayment - 月供
   * @param {number} monthlyRate - 月利率
   * @returns {array} 还款计划
   */
  static generateSchedule(loanAmount, totalMonths, monthlyPayment, monthlyRate) {
    const schedule = [];
    let remainingBalance = loanAmount;
    
    for (let i = 1; i <= totalMonths; i++) {
      const monthlyInterest = remainingBalance * monthlyRate;
      const monthlyPrincipal = monthlyPayment - monthlyInterest;
      remainingBalance -= monthlyPrincipal;
      
      schedule.push({
        period: i,
        payment: monthlyPayment,
        principal: monthlyPrincipal,
        interest: monthlyInterest,
        remainingBalance: Math.max(0, remainingBalance)
      });
    }
    
    return schedule;
  }
  
  /**
   * 提前还款计算
   * @param {object} originalCalculation - 原始计算结果
   * @param {number} earlyAmount - 提前还款金额
   * @param {Date} earlyDate - 提前还款日期
   * @returns {object} 提前还款结果
   */
  static earlyRepayment(originalCalculation, earlyAmount, earlyDate) {
    const { loanAmount, loanTerm, interestRate } = originalCalculation.input;
    const monthlyRate = interestRate / 12;
    
    // 计算提前还款时的剩余本金
    const monthsElapsed = this.getMonthsBetween(new Date(), earlyDate);
    const remainingBalance = this.calculateRemainingBalance(
      loanAmount, 
      monthlyRate, 
      originalCalculation.result.monthlyPayment, 
      monthsElapsed
    );
    
    const newLoanAmount = remainingBalance - earlyAmount;
    const newLoanTerm = loanTerm - (monthsElapsed / 12);
    
    if (newLoanAmount <= 0) {
      return {
        originalMonthlyPayment: originalCalculation.result.monthlyPayment,
        newMonthlyPayment: 0,
        interestSaved: originalCalculation.result.totalInterest,
        timeSaved: loanTerm
      };
    }
    
    const newCalculation = this.equalPayment(newLoanAmount, newLoanTerm, interestRate);
    
    return {
      originalMonthlyPayment: originalCalculation.result.monthlyPayment,
      newMonthlyPayment: newCalculation.monthlyPayment,
      interestSaved: originalCalculation.result.totalInterest - newCalculation.totalInterest,
      timeSaved: loanTerm - newLoanTerm
    };
  }
  
  /**
   * 计算剩余本金
   * @param {number} loanAmount - 贷款金额
   * @param {number} monthlyRate - 月利率
   * @param {number} monthlyPayment - 月供
   * @param {number} monthsElapsed - 已还月数
   * @returns {number} 剩余本金
   */
  static calculateRemainingBalance(loanAmount, monthlyRate, monthlyPayment, monthsElapsed) {
    if (monthlyRate === 0) {
      return loanAmount - (monthlyPayment * monthsElapsed);
    }
    
    return loanAmount * Math.pow(1 + monthlyRate, monthsElapsed) - 
           monthlyPayment * (Math.pow(1 + monthlyRate, monthsElapsed) - 1) / monthlyRate;
  }
  
  /**
   * 计算月份差
   * @param {Date} startDate - 开始日期
   * @param {Date} endDate - 结束日期
   * @returns {number} 月份差
   */
  static getMonthsBetween(startDate, endDate) {
    return (endDate.getFullYear() - startDate.getFullYear()) * 12 + 
           (endDate.getMonth() - startDate.getMonth());
  }
  
  /**
   * 利率对比分析
   * @param {number} loanAmount - 贷款金额
   * @param {number} loanTerm - 贷款期限
   * @param {array} rates - 利率数组
   * @returns {array} 对比结果
   */
  static compareInterestRates(loanAmount, loanTerm, rates) {
    return rates.map(rate => ({
      rate,
      result: this.equalPayment(loanAmount, loanTerm, rate)
    }));
  }
  
  /**
   * 计算购房成本分析
   * @param {number} housePrice - 房屋总价
   * @param {number} downPayment - 首付金额
   * @param {number} loanAmount - 贷款金额
   * @param {number} loanTerm - 贷款期限
   * @param {number} interestRate - 利率
   * @param {object} additionalCosts - 额外成本
   * @returns {object} 成本分析结果
   */
  static calculateTotalCost(housePrice, downPayment, loanAmount, loanTerm, interestRate, additionalCosts = {}) {
    const calculation = this.equalPayment(loanAmount, loanTerm, interestRate);
    
    const totalInterest = calculation.totalInterest;
    const totalPayment = calculation.totalPayment;
    const additionalCostsTotal = Object.values(additionalCosts).reduce((sum, cost) => sum + (cost || 0), 0);
    
    return {
      housePrice,
      downPayment,
      loanAmount,
      totalInterest,
      totalPayment,
      additionalCosts: additionalCostsTotal,
      totalCost: housePrice + totalInterest + additionalCostsTotal,
      monthlyPayment: calculation.monthlyPayment,
      monthlyAdditionalCosts: additionalCostsTotal / (loanTerm * 12)
    };
  }
  
  /**
   * 验证输入参数
   * @param {object} input - 输入参数
   * @returns {object} 验证结果
   */
  static validateInput(input) {
    const errors = [];
    
    if (input.loanAmount < 1000) {
      errors.push('贷款金额必须大于1000元');
    }
    
    if (input.loanTerm < 1 || input.loanTerm > 30) {
      errors.push('贷款期限必须在1-30年之间');
    }
    
    if (input.interestRate < 0.01 || input.interestRate > 0.2) {
      errors.push('利率必须在1%-20%之间');
    }
    
    if (input.earlyRepaymentAmount && input.earlyRepaymentAmount < 0) {
      errors.push('提前还款金额不能为负数');
    }
    
    return {
      isValid: errors.length === 0,
      errors
    };
  }
}

module.exports = MortgageCalculator; 